package tests;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

import urbanparks.Park;
import urbanparks.ParkSet;

/**
 * Test ParkSet class for errors in 
 * parsing/reading/writing.
 * 
 * @author Andrew Boguk
 * @version 1.0
 */
public class ParkSetTest {
  /** ParkSet class to test. */
  private ParkSet ps;
  
  
  /**
   * Setup the ParkSet class by creating it.
   */
  @Before
  public void setup() {
    ps = new ParkSet(new File("data/test/test_park.csv"));
  }
  
  /**
   * Test CSV parsing, and handling of odd
   * naming or parameter lengths.
   */
  @Test
  public void loadFromFileTest() {
    ps.loadFromFile();
    Park park;
    
    //Not case sensitive, weird label handling.
    park = ps.getPark("tESt1");
    assertEquals("Incorrect Name value.", 
        park.getName(), "test1");
    assertEquals("Incorrect Street Number value.", 
        park.getStreetNumber(), "test2");
    assertEquals("Incorrect Street value.", 
        park.getStreet(), "test3");
    assertEquals("Incorrect City value.", 
        park.getCity(), "test4");
    assertEquals("Incorrect State value.", 
        park.getState(), "test5");
    assertEquals("Incorrect Zipcode value.", 
        park.getZipcode(), "test6");
    assertEquals("Incorrect Manager Name value.", 
        park.getManagerEmail(), "test7");
    assertEquals("Incorrect Park District value.",
        park.getParkDistrict(), "test8");
    assertEquals("Incorrect Public Transportation " + 
                 "Directions value.",
        park.getPublicTransportationDirections(), "test9");
    assertEquals("Incorrect Driving Directions value.", 
        park.getDrivingDirections(), "test10");
    
    //Get good line and labels.
    park = ps.getPark("name");
    assertEquals("Incorrect Name value.", 
        park.getName(), 
        "name");
    assertEquals("Incorrect Street Number value.", 
        park.getStreetNumber(), 
        "streetnumber");
    assertEquals("Incorrect Street value.", 
        park.getStreet(), 
        "street");
    assertEquals("Incorrect City value.", 
        park.getCity(), 
        "city");
    assertEquals("Incorrect State value.", 
        park.getState(), 
        "state");
    assertEquals("Incorrect Zipcode value.", 
        park.getZipcode(), 
        "zipcode");
    assertEquals("Incorrect Manager Name value.", 
        park.getManagerEmail(), 
        "managername");
    assertEquals("Incorrect Park District value.", 
        park.getParkDistrict(), 
        "parkdistrict");
    assertEquals("Incorrect Public Transportation " +
                 "Directions value.",
        park.getPublicTransportationDirections(), 
        "transportationdirection");
    assertEquals("Incorrect Driving Directions value.", 
        park.getDrivingDirections(), 
        "drivingdirections");
    
    //Skip bad line.
    park = ps.getPark("bad1");
    assertTrue("Incomplete parameters put into map.", park == null);
  }
  
  /**
   * Tests integrity of writing to file by testing
   * if the first load passes, then re-writes the data
   * into the file, reloads the file, and tests to see
   * if the data is correct.
   */
  @Test
  public void writeFileTest() {
    loadFromFileTest();
    ps.writeFile();
    
    loadFromFileTest();
  }
  
  /**
   * Tests getting list of parks with specified
   * manager district is correct.
   */
  @Test
  public void getParksManagedByTest() {
    List<Park> p = ps.getParksManagedBy("managername");
    
    //Only one park with this manager.
    assertEquals(1, p.size());
    //Name of park with this manager is correct.
    assertEquals("name", p.get(0).getName());
    
    p = ps.getParksManagedBy("test7");
    //Only one park with this manager.
    assertEquals(1, p.size());
    //Name of park with this manager is correct.
    assertEquals("test1", p.get(0).getName());
  }
  
  /**
   * Tests getting list of parks in specified
   * region is correct.
   */
  @Test
  public void getParksInRegionTest() {
    List<Park> p = ps.getParksInRegion("city");
    
    //Only one park with this manager.
    assertEquals(1, p.size());
    //Name of park with this manager is correct.
    assertEquals("name", p.get(0).getName());
    
    p = ps.getParksManagedBy("test7");
    //Only one park with this manager.
    assertEquals(p.size(), 1);
    //Name of park with this manager is correct.
    assertEquals(p.get(0).getName(), "test1");
  }
  
  /**
   * Tests getting list of parks in specified
   * district is correct.
   */
  @Test
  public void getParksInDistrictTest() {
    List<Park> p = ps.getParksInDistrict("parkdistrict");
    
    //Only one park with this manager.
    assertEquals(1, p.size());
    //Name of park with this manager is correct.
    assertEquals("name", p.get(0).getName());
    
    p = ps.getParksManagedBy("test7");
    //Only one park with this manager.
    assertEquals(1, p.size());
    //Name of park with this manager is correct.
    assertEquals("test1", p.get(0).getName());
  }
}